
; load all other files into environment
(load "match_handler.lisp")
(load "match_checker.lisp")
(load "level_drawer.lisp")
(load "game.lisp")


; define vairables
(defconstant	*MENU-CHOICE-DIRECTIONS* 1)
(defconstant	*MENU-CHOICE-PLAY* 2)
(defconstant	*MENU-CHOICE-END* 'X)
(defvar         small-game 5)
(defvar         medium-game 6)
(defvar         large-game 7)
  
  
; Main Loop: start of program 
; 
;  
(defun main ()
  (do  ((user-input NIL))
  ( (eql user-input *MENU-CHOICE-END*) (format t "~%Thanks for playing")) (menu)
  (setf user-input  (get-input)) 
  (if  (validate-choice user-input) (dispatch-user-choice user-input)(invalid-entry-message))))


; Prompt user menu
(defun menu ()
  (format T "~5%Do you want to play a game?~%___________________________~2%~A)~TDirections~%~A)~TPlay Game~%~A)~TExit Game~2%"
  *MENU-CHOICE-DIRECTIONS* *MENU-CHOICE-PLAY* *MENU-CHOICE-END*))


; prompts user for game size, calls (defun play)
(defun game-play ()
  (format t "~%~5TSelect size of game (1)-small, (2)-medium, (3)-large: ")
  (setq user-input  (get-input))
  (if (validate-size user-input)
     (play (+ 4 (get-size user-input)) (get-size user-input))
     (invalid-entry-message)))


; checks if user input for size is valid
(defun validate-size (user-input)
  (if  (OR (eql user-input 1)(eql user-input 2)
     (eql user-input 3))T Nil))


; validate user choice
(defun validate-choice (user-input)
  (if  (OR (eql user-input *MENU-CHOICE-DIRECTIONS*)(eql user-input *MENU-CHOICE-PLAY*)
  (eql user-input *MENU-CHOICE-END*)(eql user-input 5)(eql user-input 8)
     (eql user-input 10))T Nil))


; gets size from user input
(defun get-size (size)
  (case size
    (1 small-game)
    (2 medium-game)
    (3 large-game)
    (otherwise nil)))
 

; Get user input for main menu
(defun get-input ()
  (let  ((user-input  (read))) user-input))


; Direct user input to different funftions
(defun dispatch-user-choice (user-input) (cond
  ((eql user-input *MENU-CHOICE-DIRECTIONS*)  (game-directions))
  ((eql user-input *MENU-CHOICE-PLAY*) (game-play))))


; error message for invalid user input  
(defun invalid-entry-message ()
  (format t "~2%**** Invalid entry, choose again. ****"))


; Display game directions
(defun game-directions ()
  (format t "~2%~5TDirections: To play the user must enter the size of game desired. From  
    ~17Tthere a game board is generated in a form of rows and columns.
    ~17TThe object is to score points by matching shapes of 3 or more.
    ~17TThis is done by swapping shapes from one (col row) to another
    ~17T(col row). Points are generated by the amount of shapes matched. 
    ~17TThe game ends when a set number of swaps are made or there are 
    ~17Tno more matches to make. 
    ~17T_______________________________________________________________"))